引子

原有项目是electron-vue的模板,使用的是mochababel 6, ava需求是babel 7 升级了一波babel的插件,就可以玩起来了,基本基本大部分内容:

  • @babel/core 替换 babel-core

  • @babel/preset-* 替换 babel-preset-*

  • 部分 @babel/plugin-* 替换 babel-plugin-*, 有的没有或者不影响,还是用原来的

  • 修改 .babelrc, presetplugin 前加@babel/

  • 为了保留原有的其他mocha 相关内容,单独建自己的目录,并修改package.json

    • "e2e:ava": "npm run pack && nyc ava test/e2e/ava",
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52



      `ava`使用的优势:

      - 异步支持的好, `Promise`, `Generator`, `Async`,`Observable` ,`Callback`都支持
      - 用例并行执行,效率高
      - 集成Babel 7,无伤 ES6+



      ### 启用ava

      #### 直接用ava

      - `npm i ava@latest -D && ava`
      - `ava --help` 查看相应的命令行参数



      #### 注意点

      - `ava`目前只转换测试文件,有问题需要单独处理



      ### 趟了半天的坑

      ##### electron 2.0.4 + spectron 3.8.0 OK

      ##### electron 6.1.4 + spectron 8.0.0 不好使

      ##### electron 7.1.1 + spectron 9.0.0 不好使

      原因是 没有开启`nodeIntegration`, 尴尬 [Node Integration](https://github.com/electron-userland/spectron#node-integration) , [低级问题自问自答](https://github.com/electron-userland/spectron/issues/482)

      #### 解决办法

      #### 通过 `new BrowserWindow` 的 `preload` 脚本加载, 通过环境变量来设置

      ```js
      const preloadPath = path.join(process.cwd(), 'src/common/api/renderer-preload.js')
      console.log('preloadPath:', preloadPath)
      mainWindow = new BrowserWindow({
      height: 800,
      useContentSize: true,
      width: 1260,
      webPreferences: {
      preload: preloadPath,
      nodeIntegration: false
      }
      })
1
2
3
4
// renderer-preload.js
if (process.env.NODE_ENV === 'test') {
window.electronRequire = require
}
1
2
3
4
5
6
7
8
9
10
11
// Spenctron test case
test.beforeEach(async t => {
const app = new Application({
path: electron,
args: ['dist/electron/main.js'],
requireName: 'electronRequire',
startTimeout: 10000,
waitTimeout: 10000
})
await app.start()
})
1
2
// package.json 设置环境变量
"e2e:ava": "npm run pack && cross-env NODE_ENV=test nyc ava test/e2e/ava/index.js",

直接在 new BrowserWindow 的时候配上webPreferences. nodeIntegration

1
2
3
4
5
6
7
8
mainWindow = new BrowserWindow({
height: 800,
useContentSize: true,
width: 1260,
webPreferences: {
nodeIntegration: false
}
})

主进程和渲染进程通信

用了reply函数,但函数参数中还是需要传 channelId, 这个函数与event.sender.send的区别在于, send总是发送到main frame, 而 reply是发送到任意(内部调用了sendToFrame),我错误的理解为一个是带channelId参数的,一个是不带的,其实是都需要带的

主进程通信once注册的并发问题

如果使用once注册,那么连续发送两次请求,得到的结果是一样的,需要根据请求, once 注册不同的 listener

参考资料

  1. babel 7.x 和 webpack 4.x 配置vue项目
  2. Upgrade to Babel 7
  3. ava code coverage
× 赞赏这个人~
打赏二维码